home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / demos / VisualAge for Java 2.0 Entry / setup / data1.cab / ide-e / IDE / cache / UR02MD (.txt) < prev    next >
Encoding:
Java Class File  |  1998-09-16  |  9.9 KB  |  279 lines

  1. package com.sun.java.swing.text;
  2.  
  3. import com.sun.java.swing.event.DocumentEvent;
  4. import java.awt.Color;
  5. import java.awt.Component;
  6. import java.awt.Font;
  7. import java.awt.FontMetrics;
  8. import java.awt.Graphics;
  9. import java.awt.Rectangle;
  10. import java.awt.Shape;
  11.  
  12. public class PlainView extends View implements TabExpander {
  13.    protected FontMetrics metrics;
  14.    Segment lineBuffer = new Segment();
  15.    int width;
  16.    int tabSize;
  17.    int tabBase;
  18.    JTextComponent host;
  19.    int sel0;
  20.    int sel1;
  21.    Color unselected;
  22.    Color selected;
  23.  
  24.    public PlainView(Element elem) {
  25.       super(elem);
  26.    }
  27.  
  28.    public void changedUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
  29.       this.updateDamage(changes, a, f);
  30.    }
  31.  
  32.    private void damageLineRange(int line0, int line1, Shape a, Component host) {
  33.       if (a != null) {
  34.          Rectangle area0 = this.lineToRect(a, line0);
  35.          Rectangle area1 = this.lineToRect(a, line1);
  36.          if (area0 != null && area1 != null) {
  37.             Rectangle damage = area0.union(area1);
  38.             host.repaint(damage.x, damage.y, damage.width, damage.height);
  39.          } else {
  40.             host.repaint();
  41.          }
  42.       }
  43.  
  44.    }
  45.  
  46.    protected void drawLine(int lineIndex, Graphics g, int x, int y) {
  47.       try {
  48.          Element line = ((View)this).getElement().getElement(lineIndex);
  49.          int p0 = line.getStartOffset();
  50.          int p1 = line.getEndOffset();
  51.          p1 = Math.min(((View)this).getDocument().getLength(), p1);
  52.          if (this.sel0 == this.sel1) {
  53.             this.drawUnselectedText(g, x, y, p0, p1);
  54.          } else if (p0 >= this.sel0 && p0 <= this.sel1 && p1 >= this.sel0 && p1 <= this.sel1) {
  55.             this.drawSelectedText(g, x, y, p0, p1);
  56.          } else if (this.sel0 >= p0 && this.sel0 <= p1) {
  57.             if (this.sel1 >= p0 && this.sel1 <= p1) {
  58.                x = this.drawUnselectedText(g, x, y, p0, this.sel0);
  59.                x = this.drawSelectedText(g, x, y, this.sel0, this.sel1);
  60.                this.drawUnselectedText(g, x, y, this.sel1, p1);
  61.             } else {
  62.                x = this.drawUnselectedText(g, x, y, p0, this.sel0);
  63.                this.drawSelectedText(g, x, y, this.sel0, p1);
  64.             }
  65.          } else if (this.sel1 >= p0 && this.sel1 <= p1) {
  66.             x = this.drawSelectedText(g, x, y, p0, this.sel1);
  67.             this.drawUnselectedText(g, x, y, this.sel1, p1);
  68.          } else {
  69.             this.drawUnselectedText(g, x, y, p0, p1);
  70.          }
  71.  
  72.       } catch (BadLocationException var8) {
  73.          throw new StateInvariantError("Can't render line: " + lineIndex);
  74.       }
  75.    }
  76.  
  77.    protected int drawSelectedText(Graphics g, int x, int y, int p0, int p1) throws BadLocationException {
  78.       g.setColor(this.selected);
  79.       Document doc = ((View)this).getDocument();
  80.       doc.getText(p0, p1 - p0, this.lineBuffer);
  81.       return Utilities.drawTabbedText(this.lineBuffer, x, y, g, this, p0);
  82.    }
  83.  
  84.    protected int drawUnselectedText(Graphics g, int x, int y, int p0, int p1) throws BadLocationException {
  85.       g.setColor(this.unselected);
  86.       Document doc = ((View)this).getDocument();
  87.       doc.getText(p0, p1 - p0, this.lineBuffer);
  88.       return Utilities.drawTabbedText(this.lineBuffer, x, y, g, this, p0);
  89.    }
  90.  
  91.    protected final Segment getLineBuffer() {
  92.       return this.lineBuffer;
  93.    }
  94.  
  95.    protected int getLineLimit() {
  96.       Integer lineLimit = (Integer)((View)this).getDocument().getProperty("lineLimit");
  97.       if (lineLimit == null) {
  98.          int width = 0;
  99.          int totalLines = ((View)this).getElement().getElementCount();
  100.  
  101.          for(int i = 0; i < totalLines; ++i) {
  102.             Element line = ((View)this).getElement().getElement(i);
  103.             int p0 = line.getStartOffset();
  104.             int p1 = line.getEndOffset();
  105.             if (p1 - p0 > width) {
  106.                width = p1 - p0;
  107.             }
  108.          }
  109.  
  110.          lineLimit = new Integer(width);
  111.          ((View)this).getDocument().putProperty("lineLimit", lineLimit);
  112.       }
  113.  
  114.       return lineLimit;
  115.    }
  116.  
  117.    public float getPreferredSpan(int axis) {
  118.       this.updateMetrics();
  119.       switch (axis) {
  120.          case 0:
  121.             return (float)this.width;
  122.          case 1:
  123.             return (float)(((View)this).getElement().getElementCount() * this.metrics.getHeight());
  124.          default:
  125.             throw new IllegalArgumentException("Invalid axis: " + axis);
  126.       }
  127.    }
  128.  
  129.    protected int getTabSize() {
  130.       Integer i = (Integer)((View)this).getDocument().getProperty("tabSize");
  131.       int size = i != null ? i : 8;
  132.       return size;
  133.    }
  134.  
  135.    public void insertUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
  136.       this.updateDamage(changes, a, f);
  137.    }
  138.  
  139.    private Rectangle lineToRect(Shape a, int line) {
  140.       Rectangle r = null;
  141.       if (this.metrics != null) {
  142.          Rectangle alloc = a.getBounds();
  143.          r = new Rectangle(alloc.x, alloc.y + line * this.metrics.getHeight(), alloc.width, this.metrics.getHeight());
  144.       }
  145.  
  146.       return r;
  147.    }
  148.  
  149.    public Shape modelToView(int pos, Shape a) throws BadLocationException {
  150.       Document doc = ((View)this).getDocument();
  151.       Element map = ((View)this).getElement();
  152.       int lineIndex = map.getElementIndex(pos);
  153.       Rectangle lineArea = this.lineToRect(a, lineIndex);
  154.       this.tabBase = lineArea.x;
  155.       Element line = map.getElement(lineIndex);
  156.       int p0 = line.getStartOffset();
  157.       doc.getText(p0, pos - p0, this.lineBuffer);
  158.       int xOffs = Utilities.getTabbedTextWidth(this.lineBuffer, this.metrics, this.tabBase, this, p0);
  159.       lineArea.x += xOffs;
  160.       lineArea.width = 1;
  161.       lineArea.height = this.metrics.getHeight();
  162.       return lineArea;
  163.    }
  164.  
  165.    public float nextTabStop(float x, int tabOffset) {
  166.       int ntabs = ((int)x - this.tabBase) / this.tabSize;
  167.       return (float)(this.tabBase + (ntabs + 1) * this.tabSize);
  168.    }
  169.  
  170.    public void paint(Graphics g, Shape a) {
  171.       Rectangle alloc = (Rectangle)a;
  172.       this.tabBase = alloc.x;
  173.       g.setFont(this.host.getFont());
  174.       this.sel0 = this.host.getSelectionStart();
  175.       this.sel1 = this.host.getSelectionEnd();
  176.       this.unselected = this.host.isEnabled() ? this.host.getForeground() : this.host.getDisabledTextColor();
  177.       Caret c = this.host.getCaret();
  178.       this.selected = c.isSelectionVisible() ? this.host.getSelectedTextColor() : this.unselected;
  179.       this.updateMetrics();
  180.       Rectangle clip = g.getClipBounds();
  181.       int fontHeight = this.metrics.getHeight();
  182.       int heightBelow = alloc.y + alloc.height - (clip.y + clip.height);
  183.       int linesBelow = Math.max(0, heightBelow / fontHeight);
  184.       int heightAbove = clip.y - alloc.y;
  185.       int linesAbove = Math.max(0, heightAbove / fontHeight);
  186.       int linesTotal = alloc.height / fontHeight;
  187.       Rectangle lineArea = this.lineToRect(a, linesAbove);
  188.       int y = lineArea.y + this.metrics.getAscent();
  189.       int x = lineArea.x;
  190.       Element map = ((View)this).getElement();
  191.       int endLine = Math.min(map.getElementCount(), linesTotal - linesBelow);
  192.  
  193.       for(int line = linesAbove; line < endLine; ++line) {
  194.          this.drawLine(line, g, x, y);
  195.          y += fontHeight;
  196.       }
  197.  
  198.    }
  199.  
  200.    public void preferenceChanged(View child, boolean width, boolean height) {
  201.       ((View)this).getDocument().putProperty("lineLimit", (Object)null);
  202.       super.preferenceChanged(child, width, height);
  203.    }
  204.  
  205.    public void removeUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
  206.       this.updateDamage(changes, a, f);
  207.    }
  208.  
  209.    public void setParent(View p) {
  210.       super.setParent(p);
  211.       this.host = (JTextComponent)((View)this).getContainer();
  212.    }
  213.  
  214.    void updateDamage(DocumentEvent changes, Shape a, ViewFactory f) {
  215.       if (this.host.isShowing()) {
  216.          this.updateMetrics();
  217.          Element elem = ((View)this).getElement();
  218.          DocumentEvent.ElementChange ec = changes.getChange(elem);
  219.          Element[] added = ec != null ? ec.getChildrenAdded() : null;
  220.          Element[] removed = ec != null ? ec.getChildrenRemoved() : null;
  221.          if ((added == null || added.length <= 0) && (removed == null || removed.length <= 0)) {
  222.             this.preferenceChanged((View)null, true, false);
  223.             Element map = ((View)this).getElement();
  224.             int line = map.getElementIndex(changes.getOffset());
  225.             this.damageLineRange(line, line, a, this.host);
  226.          } else {
  227.             this.preferenceChanged((View)null, true, true);
  228.             this.host.repaint();
  229.          }
  230.       }
  231.  
  232.    }
  233.  
  234.    final void updateMetrics() {
  235.       Component host = ((View)this).getContainer();
  236.       Font f = host.getFont();
  237.       this.metrics = host.getFontMetrics(f);
  238.       int columnWidth = this.metrics.charWidth('m');
  239.       this.width = this.getLineLimit() * columnWidth;
  240.       this.tabSize = this.getTabSize() * columnWidth;
  241.    }
  242.  
  243.    public int viewToModel(float fx, float fy, Shape a) {
  244.       Rectangle alloc = a.getBounds();
  245.       Document doc = ((View)this).getDocument();
  246.       int x = (int)fx;
  247.       int y = (int)fy;
  248.       if (y < alloc.y) {
  249.          return ((View)this).getStartOffset();
  250.       } else if (y > alloc.y + alloc.height) {
  251.          return ((View)this).getEndOffset() - 1;
  252.       } else {
  253.          Element map = doc.getDefaultRootElement();
  254.          int lineIndex = Math.abs((y - alloc.y) / this.metrics.getHeight());
  255.          if (lineIndex >= map.getElementCount()) {
  256.             return ((View)this).getEndOffset() - 1;
  257.          } else {
  258.             Element line = map.getElement(lineIndex);
  259.             if (x < alloc.x) {
  260.                return line.getStartOffset();
  261.             } else if (x > alloc.x + alloc.width) {
  262.                return line.getEndOffset() - 1;
  263.             } else {
  264.                try {
  265.                   int p0 = line.getStartOffset();
  266.                   int p1 = line.getEndOffset() - 1;
  267.                   doc.getText(p0, p1 - p0, this.lineBuffer);
  268.                   this.tabBase = alloc.x;
  269.                   int offs = p0 + Utilities.getTabbedTextOffset(this.lineBuffer, this.metrics, this.tabBase, x, this, p0);
  270.                   return offs;
  271.                } catch (BadLocationException var14) {
  272.                   return -1;
  273.                }
  274.             }
  275.          }
  276.       }
  277.    }
  278. }
  279.